1 module project.gen; 2 import std.path:buildNormalizedPath; 3 import std.file; 4 import std.format:format; 5 import std.process; 6 import std.array:join,split,array; 7 8 struct TemplateInfo 9 { 10 string initMethod=q{ 11 setFont(HipDefaultAssets.getDefaultFontWithSize(62)); 12 }, 13 update="", 14 render=q{ 15 drawText("You can start using the D Scripting API Here!", 400, 300, HipColor.white, 16 HipTextAlign.CENTER, HipTextAlign.CENTER 17 ); 18 }, 19 dispose=""; 20 } 21 22 struct DubProjectInfo 23 { 24 string author = "HipremeEngine"; 25 string projectName = "Hipreme Engine Test"; 26 string desc = "Hipreme Engine test scene"; 27 } 28 29 string generateCodeTemplate(TemplateInfo info = TemplateInfo()) 30 { 31 return format!q{ 32 module gamescript.entry; 33 import hip.api; 34 35 /** 36 * Call `dub` to generate the DLL, after that, just execute `dub -c run` for starting your project 37 */ 38 class MainScene : AScene, IHipPreloadable 39 { 40 mixin Preload; 41 42 /** Constructor */ 43 override void initialize() 44 { 45 %s 46 } 47 /** Called every frame */ 48 override void update(float dt) 49 { 50 %s 51 } 52 /** Renderer only, may not be called every frame */ 53 override void render() 54 { 55 %s 56 } 57 /** Pre destroy */ 58 override void dispose() 59 { 60 %s 61 } 62 void onResize(uint width, uint height){} 63 } 64 65 mixin HipEngineMain!MainScene; 66 }(info.initMethod, info.update, info.render, info.dispose); 67 } 68 69 70 string escapeWindowsPathSep(string input) 71 { 72 string output = ""; 73 foreach(ch; input) 74 if(ch == '\\') 75 output~="\\\\"; 76 else 77 output~= ch; 78 return output; 79 } 80 81 string generateDubProject(DubProjectInfo info) 82 { 83 import std.conv; 84 import std.uni:toLower; 85 import std.algorithm:map; 86 dstring outputName = info.projectName.split(" ").join("_").array; 87 dstring name = outputName.map!(character => character.toLower).array; 88 89 return format!`{ 90 "$schema": "https://raw.githubusercontent.com/Pure-D/code-d/master/json-validation/dub.schema.json", 91 "authors": ["%s"], 92 "description" : "%s", 93 "license": "proprietary", 94 "targetName" : "%s", 95 "name" : "%s", 96 "engineModules": [ 97 "util", 98 "timer", 99 "tween", 100 "math" 101 ], 102 "stringImportPaths": [ 103 "#PROJECT" 104 ], 105 "dflags-ldc": ["--disable-verify", "--oq"], 106 "preBuildCommands-posix": [ 107 "export DFLAGS= && rdmd #HIPREME_ENGINE/tools/build/getmodules.d #PROJECT/source/ #PROJECT/scriptmodules.txt" 108 ], 109 "preBuildCommands-windows": [ 110 "set DFLAGS= && rdmd #HIPREME_ENGINE/tools/build/getmodules.d #PROJECT/source/ #PROJECT/scriptmodules.txt" 111 ], 112 "configurations": 113 [ 114 { 115 "name" : "script", 116 "targetType": "dynamicLibrary", 117 "dflags-ldc": ["-link-defaultlib-shared=true"], 118 "linkedDependencies": {"hipengine_api": {"path": "#HIPREME_ENGINE/api"}}, 119 "lflags-windows": ["/WX"], 120 "versions": ["ScriptAPI"] 121 }, 122 { 123 "name": "release", 124 "targetType": "staticLibrary", 125 "dependencies": {"hipengine_api:direct": {"path": "#HIPREME_ENGINE/api"}} 126 }, 127 { 128 "name": "run", 129 "targetType": "dynamicLibrary", 130 "lflags-windows": [ 131 "/WX" 132 ], 133 "postGenerateCommands-windows": ["cd /d #HIPREME_ENGINE && dub -c script -- $PACKAGE_DIR"], 134 "postGenerateCommands-linux": ["cd #HIPREME_ENGINE && dub -c script -- $PACKAGE_DIR"] 135 } 136 ], 137 "versions" : [ 138 "HipMathAPI", 139 "HipremeAudio" 140 ] 141 } 142 `(info.author, info.desc, outputName, name); 143 } 144 145 string generateReadmeContent(string projectName) 146 { 147 return "# "~projectName~"\n"~projectName~" is made using Hipreme Engine.\n" ~ 148 "## Building Instructions \n" ~ 149 "1. Run `dub hipreme_engine:build_selector`\n" ~ 150 "2. Select 'Select Game'\n" ~ 151 "3. Select the folder containing "~projectName~"\n"~ 152 "4. Now you can simply choose the platform to build for"; 153 } 154 155 string generateVSCodeDebuggerLaunch(string enginePath) 156 { 157 import std.system; 158 string hipEnginePath = enginePath; 159 string hipEngineExecutable = (buildNormalizedPath(hipEnginePath, "bin", "desktop", "hipreme_engine") ~ ((os == OS.linux) ? "" : ".exe")).escapeWindowsPathSep; 160 return format!q{ 161 { 162 // Use IntelliSense to learn about possible attributes. 163 // Hover to view descriptions of existing attributes. 164 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 165 // Auto Generated by HipremeEngine project generator. 166 // Automatically handle SIGUSR1 and SIGUSR2 as they are currently used in semaphore.wait 167 "version": "0.2.0", 168 "configurations": [ 169 { 170 "name": "Debug", 171 "type": "gdb", 172 "request": "launch", 173 "target": "%s", 174 "cwd": "${workspaceRoot}", 175 "arguments": "${workspaceRoot}", 176 "debugger_args": [ 177 "-ex", "handle SIGUSR1 noprint", 178 "-ex", "handle SIGUSR2 noprint" 179 ] 180 } 181 ] 182 } 183 }(hipEngineExecutable); 184 } 185 186 import commons; 187 bool generateProject(ref Terminal t, string projectPath, string enginePath, 188 DubProjectInfo dubInfo, TemplateInfo templateInfo) 189 { 190 string dubProj = generateDubProject(dubInfo); 191 string codeTemplate = generateCodeTemplate(templateInfo); 192 string debugLauncher = generateVSCodeDebuggerLaunch(enginePath); 193 194 try 195 { 196 //Project folder 197 t.writeln("Creating project folder"); 198 mkdirRecurse(projectPath); 199 //Source Folder 200 t.writeln("Creating scripts folder"); 201 mkdirRecurse(buildNormalizedPath(projectPath, "source", "gamescript")); 202 //Assets Folder 203 t.writeln("Creating assets folder"); 204 mkdirRecurse(buildNormalizedPath(projectPath, "assets")); 205 //VSCode Folder 206 t.writeln("Creating vscode folder"); 207 mkdirRecurse(buildNormalizedPath(projectPath, ".vscode")); 208 209 t.writeln("Writing code template for gamescript/entry.d"); 210 std.file.write(buildNormalizedPath(projectPath, "source", "gamescript", "entry.d"), codeTemplate); 211 t.writeln("Writing dub.template.json"); 212 std.file.write(buildNormalizedPath(projectPath, "dub.template.json"), dubProj); 213 t.writeln("Writing README.md"); 214 std.file.write(buildNormalizedPath(projectPath, "README.md"), generateReadmeContent(dubInfo.projectName)); 215 t.writeln("Writing VSCode debug launcher"); 216 std.file.write(buildNormalizedPath(projectPath, ".vscode", "launch.json"), debugLauncher); 217 218 t.writeln("Writing .gitignore"); 219 std.file.write(buildNormalizedPath(projectPath, ".gitignore"), q{ 220 dub.selections.json 221 .DS_Store 222 .dub 223 .history 224 .vs 225 bin 226 *.exe 227 *.dll 228 *.dll_hiptempdll 229 *.so 230 *.lib 231 *.a 232 *.pdb 233 }); 234 } 235 catch(Exception e) 236 { 237 t.writelnError(e.toString); 238 return false; 239 } 240 return true; 241 }